package a.b.c;

import java.util.HashMap;
import android.content.Context;
import android.database.Cursor;
import android.database.CursorWrapper;
import android.support.v4.widget.CursorAdapter;
import android.support.v4.widget.ResourceCursorAdapter;
import android.text.TextUtils;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

public abstract class SectionCursorAdatper extends ResourceCursorAdapter {
	private LayoutInflater mInflater;
	private String mSectionColumnName;
	private int mLayout;
	private CursorAdapter mAdapter;

	public SectionCursorAdatper(Context context, int sectionLayout, CursorAdapter adapter, String sectionColumnName) {
		super(context, 0, new SectionCursor(adapter.getCursor(), sectionColumnName), true);
		init(context, sectionLayout, sectionColumnName);
		mAdapter = adapter;
	}

	private void init(Context context, int layout, String sectionColumnName) {
		mLayout = layout;
		mSectionColumnName = sectionColumnName;
		mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
	}

	@Override
	public Cursor swapCursor(Cursor newCursor) {
		return super.swapCursor(new SectionCursor(newCursor, mSectionColumnName));
	}

	@Override
	public View newView(Context context, Cursor cursor, ViewGroup parent) {
		int positon = cursor.getPosition();
		if (isSection(positon)) {
			return mInflater.inflate(mLayout, null);
		} else {
			// TODO
			if (mAdapter != null) {
				return mAdapter.newView(context, cursor, parent);
			}
			return super.newView(context, cursor, parent);
		}
	}

	@Override
	public void bindView(View view, Context context, Cursor cursor) {
		int positon = cursor.getPosition();
		if (isSection(positon)) {
			bindSectionView(view, context, cursor);
		} else {
			// TODO
			if (mAdapter != null) {
				mAdapter.bindView(view, context, cursor);
			} else {
				bindContentView(view, context, cursor);
			}
		}
	}

	private boolean isSection(int position) {
		return getItemId(position) == 0;
	}

	@Override
	public int getItemViewType(int position) {
		if (isSection(position)) {
			return 1;
		}
		// TODO
		if (mAdapter != null) {
			return mAdapter.getItemViewType(position);
		}
		return super.getItemViewType(position);
	}
	@Override
	public int getViewTypeCount() {
		// TODO
		if (mAdapter != null) {
			return mAdapter.getViewTypeCount() + 1;
		}
		return super.getViewTypeCount() + 1;
	}

	@Override
	public boolean areAllItemsEnabled() {
		return false;
	}

	@Override
	public boolean isEnabled(int position) {
		return !isSection(position);
	}

	protected void bindContentView(View view, Context context, Cursor cursor) {
	};
	protected abstract void bindSectionView(View view, Context context, Cursor cursor);

	private static class SectionCursor extends CursorWrapper {
		private static final String TAG = "SectionCursor";

		private HashMap<Integer, Integer> mIndexMap = new HashMap<Integer, Integer>();
		private HashMap<Integer, String> mSectionMap = new HashMap<Integer, String>();
		private boolean mSectionRow;
		private int mSectionIndex;
		private int mPosition;

		public SectionCursor(Cursor cursor, String sectionColumnName) {
			super(cursor);
			Log.d(TAG, "create section cursor:start, count=" + cursor.getCount());
			mSectionIndex = cursor.getColumnIndexOrThrow(sectionColumnName);
			String section = null;
			String firstLetter = null;
			String prevLetter = null;
			int position = 0;
			cursor.moveToPosition(-1);
			while (cursor.moveToNext()) {

				// section
				section = cursor.getString(mSectionIndex);
				if (TextUtils.isEmpty(section)) {
					section = "etc";
				}

				// firstLetter
				firstLetter = String.valueOf(section.charAt(0));
				if (!firstLetter.equalsIgnoreCase(prevLetter)) {
					// register section
					mSectionMap.put(position++, firstLetter);
				}

				// register swap position
				mIndexMap.put(position++, cursor.getPosition());

				prevLetter = firstLetter;
			}
			Log.d(TAG, "create section cursor:end, count=" + getCount());
		}

		@Override
		public int getCount() {
			// cursor count + section count
			return super.getCount() + mSectionMap.size();
		}

		@Override
		public int getPosition() {
			return mPosition;
		}

		@Override
		public boolean moveToPosition(int position) {
			mPosition = position;
			if (mIndexMap.containsKey(mPosition)) {
				mSectionRow = false;
				return super.moveToPosition(mIndexMap.get(mPosition));
			}
			mSectionRow = true;
			return true;
		}

		@Override
		public String getString(int columnIndex) {
			if (mSectionRow) {
				if (mSectionIndex == columnIndex) {
					return mSectionMap.get(mPosition);
				} else {
					return null;
				}
			}
			return super.getString(columnIndex);
		}

		@Override
		public long getLong(int columnIndex) {
			if (mSectionRow) {
				return 0;
			}
			return super.getLong(columnIndex);
		}

		@Override
		public double getDouble(int columnIndex) {
			if (mSectionRow) {
				return 0.0d;
			}
			return super.getDouble(columnIndex);
		}

		@Override
		public float getFloat(int columnIndex) {
			if (mSectionRow) {
				return 0.0f;
			}
			return super.getFloat(columnIndex);
		}

		@Override
		public int getInt(int columnIndex) {
			if (mSectionRow) {
				return 0;
			}
			return super.getInt(columnIndex);
		}

		@Override
		public short getShort(int columnIndex) {
			if (mSectionRow) {
				return 0;
			}
			return super.getShort(columnIndex);
		}

		@Override
		public byte[] getBlob(int columnIndex) {
			if (mSectionRow) {
				return null;
			}
			return super.getBlob(columnIndex);
		}
	}
}
